#include "head.h"

/* 
 * 功能：将时间戳转换为可读的日期时间字符串
 * 输出格式示例："Jan 01 12:34"
 */
int timetrans(time_t dtime, char *buf) {
    char month_arr[][4] = {"Jan","Feb","Mar","Apr","May","Jun",
                          "Jul","Aug","Sep","Oct","Nov","Dec"};
    
    // 将time_t转换为tm结构体
    struct tm* st_tm = localtime(&dtime);
    
    // 格式化输出：月份 日期 小时:分钟
    sprintf(buf, "%s %02d %02d:%02d",
            month_arr[st_tm->tm_mon],  // 获取月份缩写
            st_tm->tm_mday,           // 获取日期(1-31)
            st_tm->tm_hour,           // 获取小时(0-23)
            st_tm->tm_min);           // 获取分钟(0-59)
    return 0;
}

/*
 * 功能：将文件模式转换为ls -l风格的权限字符串
 * 输出格式示例："drwxr-xr-x"
 */
int mode_trans(mode_t mode, char *buf) {
    // 处理文件类型
    switch(mode & S_IFMT) {
    case S_IFBLK: buf[0] = 'b'; break;  // 块设备文件
    case S_IFCHR: buf[0] = 'c'; break;  // 字符设备文件
    case S_IFDIR: buf[0] = 'd'; break;  // 目录
    case S_IFIFO: buf[0] = 'p'; break;  // 管道文件
    case S_IFLNK: buf[0] = 'l'; break;  // 符号链接
    case S_IFREG: buf[0] = '-'; break;  // 普通文件
    case S_IFSOCK: buf[0] = 's'; break; // 套接字文件
    default: buf[0] = '?'; break;       // 未知类型
    }

    // 处理用户权限
    buf[1] = mode & 0400 ? 'r' : '-';  // 用户读权限
    buf[2] = mode & 0200 ? 'w' : '-';  // 用户写权限
    buf[3] = mode & 0100 ? 'x' : '-';  // 用户执行权限
    
    // 处理组权限
    buf[4] = mode & 0040 ? 'r' : '-';  // 组读权限
    buf[5] = mode & 0020 ? 'w' : '-';  // 组写权限
    buf[6] = mode & 0010 ? 'x' : '-';  // 组执行权限
    
    // 处理其他用户权限
    buf[7] = mode & 0004 ? 'r' : '-';  // 其他用户读权限
    buf[8] = mode & 0002 ? 'w' : '-';  // 其他用户写权限
    buf[9] = mode & 0001 ? 'x' : '-';  // 其他用户执行权限
    
    buf[10] = '\0';  // 字符串结束符
    return 0;
}

/*
 * 功能：生成ls -l风格的详细文件信息
 * 输出格式示例："-rw-r--r-- 1 user group 1234 Jan 01 12:34 filename"
 */
int ls_l(char *buf, int size, struct dirent *entry) {
    struct stat statbuf;
    
    // 获取文件状态信息
    int ret = stat(entry->d_name, &statbuf);
    if (ret == -1) {
        // 错误处理：将错误信息写入buf
        strerror_r(errno, buf, size);
        return -1;
    }
    
    char mode_buf[16] = {0};
    mode_trans(statbuf.st_mode, mode_buf);  // 转换文件模式
    
    // 获取用户名和组名
    char *username = getpwuid(statbuf.st_uid)->pw_name;
    char *groupname = getgrgid(statbuf.st_gid)->gr_name;
    
    char time_buf[1024] = {0};
    timetrans(statbuf.st_mtim.tv_sec, time_buf);  // 转换时间格式
    
    // 格式化输出完整文件信息
    sprintf(buf, "%s %2lu %-5s %-5s %6lu %s %s\n",
            mode_buf,            // 文件权限字符串
            statbuf.st_nlink,    // 硬链接数
            username,           // 所属用户
            groupname,          // 所属组
            statbuf.st_size,    // 文件大小(字节)
            time_buf,          // 修改时间
            entry->d_name);     // 文件名
    
    return 0;
}

